home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / tool / artemis1 / src / sub.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-17  |  21.1 KB  |  993 lines

  1. /*
  2.     ARTemis (Graphic Editor for FM-TOWNS)
  3.     (c) MATSUUCHI Ryosuke 1992
  4.  
  5.     sub.c
  6.  
  7.     補助処理モジュール
  8.  
  9.  
  10.     page_menu            書き込みページをメニュー用ページに
  11.     page_edit            書き込みページを描画用ページに
  12.  
  13.     trans_fname_ext        ファイル名の拡張子を置き換える
  14.     getfsize            あるファイルの大きさを得る
  15.     resetfattr            ファイルの属性をクリアする
  16.  
  17.     cbuf_init            濃度バッファ・初期化
  18.     cbuf_clear            濃度バッファ・クリア
  19.     cbuf_adrs            濃度バッファ・指定座標のアドレス取得
  20.     cbuf_getlinesize    
  21.     cbuf_mix
  22.  
  23.     scrollForCsr        カーソル座標が画面内にくるようスクロール
  24.     limitCsrPos            カーソル座標の制限
  25.  
  26.     area_init            領域指定処理の初期化
  27.     area_input            矩形/ポリゴンによる領域の入力
  28.     area_chkxy            ある座標が、指定領域内かどうかを調べる
  29.     area_chkxy2            (x,y)-(x+1,y+1)が、指定領域内かどうかを調べる
  30.     area_chkxylen        ある座標から右に何ドット同じフラグが連続しているか
  31.     area_getboundxy        指定領域を囲む最小の矩形を得る
  32.  
  33.     hline_func            マスクされていない部分だけに描画する
  34. */
  35.  
  36. #include <stdio.h>
  37. #include <stdefs.h>
  38. #include <egb.h>
  39. #include <malloc.h>
  40. #include <stdlib.h>
  41. #include <msdos.cf>
  42. #include <memory.h>
  43. // #include <interrup.cf>
  44. #include <math.h>
  45. #include <dos.h>
  46.  
  47. void FM_ResetVector(void);
  48. void FM_SetVector(void);
  49.  
  50. #include "ge.h"
  51. #include "plt16.h"
  52. #include "dispman.h"
  53. #include "imageman.h"
  54. #include "mask.h"
  55.  
  56. /*--------------------------------------------------------*/
  57. /*                     ページ切り換え                     */
  58. /*--------------------------------------------------------*/
  59.  
  60.  
  61. void page_menu()
  62. {
  63.     gwrtpage(0);
  64. }
  65.  
  66.  
  67. void page_edit()
  68. {
  69.     if (!DMgetifonepage())
  70.         gwrtpage(1);
  71.     else
  72.         gwrtpage(0);
  73. }
  74.  
  75. /*--------------------------------------------------------*/
  76. /*                 ファイルの大きさを得る                 */
  77. /*--------------------------------------------------------*/
  78.  
  79. int getfsize(char *fname)
  80. {
  81.     struct find_t dirbuf;
  82.     if (_dos_findfirst(fname, _A_NORMAL, &dirbuf) == 0)
  83.         return dirbuf.size;
  84.     else
  85.         return -1;
  86. }
  87.  
  88. /*--------------------------------------------------------*/
  89. /*               ファイルの属性をクリアする               */
  90. /*--------------------------------------------------------*/
  91.  
  92. int resetfattr(char *fname)
  93. {
  94.     if (_dos_setfileattr(fname, _A_ARCH | _A_NORMAL) == 0)
  95.         return 0;
  96.     else
  97.         return -1;
  98. }
  99.  
  100. bool fexist(char *fname)
  101. {
  102.     unsigned int b;
  103.     if (_dos_getfileattr(fname, &b) == 0)
  104.         return YES;
  105.     else
  106.         return NO;
  107. }
  108.  
  109. /*--------------------------------------------------------*/
  110. /*                       文字列操作                       */
  111. /*--------------------------------------------------------*/
  112.  
  113.  
  114. char *trans_fname_ext(char *fname, char *newext)
  115. /*
  116.     ファイル名 fname の拡張子を newext に置き換えたファイル名を返す
  117. */
  118. {
  119.     static char path_buf[_MAX_PATH];
  120.     char drive[_MAX_DRIVE], dir[_MAX_DIR], basename[_MAX_FNAME], ext[_MAX_EXT];
  121.     _splitpath(fname, drive, dir, basename, ext);
  122.     _makepath(path_buf, drive, dir, basename, newext);
  123.     return path_buf;
  124. }
  125.  
  126.  
  127. void add_fname_ext(char *buf, char *fname, char *newext)
  128. /*
  129.     ファイル名 fname に拡張子が無い場合、newext を拡張子として加える
  130. */
  131. {
  132.     char drive[_MAX_DRIVE], dir[_MAX_DIR], basename[_MAX_FNAME], ext[_MAX_EXT];
  133.     _splitpath(fname, drive, dir, basename, ext);
  134.     if (ext[0] == '\0')
  135.         _makepath(buf, drive, dir, basename, newext);
  136.     else
  137.         _makepath(buf, drive, dir, basename, ext);
  138. }
  139.  
  140.  
  141. /*--------------------------------------------------------*/
  142. /*                   濃度バッファの扱い                   */
  143. /*--------------------------------------------------------*/
  144.  
  145.  
  146. // 濃度バッファは、1ドットが1バイトに対応するバッファ。
  147. //  各バイトには、「(描画したい濃度)-1」の値(0..255)が入る。
  148. // ★★ 将来、編集バッファサイズ変更機能を加えたときはこのままではダメ
  149.  
  150.  
  151. static    char*    cbuf = NULL;
  152. static    int        cbuf_xsize,cbuf_ysize;
  153.  
  154.  
  155. int cbuf_init()
  156. {
  157.     cbuf_xsize = EIMgetxsize();
  158.     cbuf_ysize = EIMgetysize();
  159.     if ((cbuf = malloc(cbuf_xsize*cbuf_ysize)) == NULL)
  160.         return -1;
  161.     memset(cbuf,0,cbuf_xsize*cbuf_ysize);
  162.     return 0;
  163. }
  164.  
  165.  
  166. void cbuf_clear()
  167. {
  168.     memset(cbuf,0,cbuf_xsize*cbuf_ysize);
  169. }
  170.  
  171.  
  172. char *cbuf_adrs(int x, int y)
  173. {
  174.     return cbuf+y*cbuf_xsize+x;
  175. }
  176.  
  177.  
  178. int cbuf_getlinesize()
  179. {
  180.     return cbuf_xsize;
  181. }
  182.  
  183.  
  184. int cbuf_mix(int c0, int rate, int maxconc)
  185. {
  186.     int c;
  187.     if (rate == 0 || c0 >= maxconc)
  188.         return c0;
  189.     else if (rate == 256)
  190.         return maxconc;
  191.     c = (c0 * (256-rate) + maxconc * rate + 255) >> 8;
  192.     if (c == c0)
  193.         return _min(c+1,maxconc);
  194.     else
  195.         return _min(c,maxconc);
  196. }
  197.  
  198.  
  199. /*--------------------------------------------------------*/
  200. /*                       スクロール                       */
  201. /*--------------------------------------------------------*/
  202.  
  203.  
  204. void scrollForCsr(int xlen,int ylen)
  205. // (ms.x,ms.y)-len(xlen,ylen) の範囲が画面内にくるようにスクロール
  206. {
  207.     int dispx,dispy,dispxlen,dispylen;
  208.     int zr=DMimage_getzoomrate();
  209.     DMimage_getdispxy(&dispx,&dispy);
  210.     DMimage_getdispxylen(&dispxlen,&dispylen);
  211.     int pre_dispx,pre_dispy;
  212.     bool mschg;
  213.     pre_dispx = dispx, pre_dispy = dispy;
  214.     mschg = NO;
  215.     while (ms.x+xlen-1>=DMgetxsize()) {
  216.         if (dispx + dispxlen < EIMgetxsize())
  217.             ms.x -= zr,  dispx++,  mschg = YES;
  218.         else
  219.             ms.x=DMgetxsize()-xlen,  mschg = YES;
  220.     }
  221.     while (ms.x<0) {
  222.         if (dispx > 0)
  223.             ms.x += zr,  dispx--,  mschg = YES;
  224.         else
  225.             ms.x=0,  mschg = YES;
  226.     }
  227.     while (ms.y+ylen-1>=DMgetysize()) {
  228.         if (dispy + dispylen < EIMgetysize())
  229.             ms.y -= zr,  dispy++,  mschg = YES;
  230.         else
  231.             ms.y=DMgetysize()-ylen,  mschg = YES;
  232.     }
  233.     while (ms.y<0) {
  234.         if (dispy > 0)
  235.             ms.y += zr,  dispy--, mschg = YES;
  236.         else
  237.             ms.y=0,  mschg = YES;
  238.     }
  239.     if (mschg)
  240.         mous_setpos(&ms, ms.x, ms.y);
  241.     if (pre_dispx!=dispx || pre_dispy!=dispy)
  242.         DMimage_setdispxy(dispx,dispy);
  243. }
  244.  
  245.  
  246. void limitCsrPos()    // カーソルの座標の制限処理
  247. {
  248.     bool mschg = NO;
  249.     if (ms.x < 0)
  250.         ms.x = 0, mschg = YES;
  251.     else if (ms.x >= DMgetxsize())
  252.         ms.x = DMgetxsize()-1, mschg = YES;
  253.     if (ms.y < 0)
  254.         ms.y = 0, mschg = YES;
  255.     else if (ms.y > DMgetysize())
  256.         ms.y = DMgetysize()-1, mschg = YES;
  257.     if (mschg)
  258.         mous_setpos(&ms, ms.x, ms.y);
  259. }
  260.  
  261.  
  262. /*--------------------------------------------------------*/
  263. /*             矩形/ポリゴンによる領域の入力             */
  264. /*--------------------------------------------------------*/
  265.  
  266.  
  267. static char *area_buf = NULL;
  268. static bool areasizevar = NO;    // 領域指定バッファの縦横サイズが可変かどうか
  269. static int areaxlen, areaylen;    // areasizevar=YES時のバッファの縦横サイズ
  270. static int ax1,ay1,ax2,ay2;        // 指定領域を囲む最小矩形
  271. #define    XBUFMAX        10            /* 1ラインにつき、x 座標をいくつ記憶するか */
  272. #define    RIGHTMAX    0x7fff
  273. typedef short int    areapos;
  274. static areapos **xbuf = NULL;    // ポリゴン指定用ワーク
  275. #define    MAXP    1024
  276. static areapos *px=NULL,*py=NULL;  // ポリゴンの輪郭保存用
  277. static short int pnum;
  278.  
  279. #define    AREAXLEN    512
  280.  
  281. int area_init()
  282. // 返値: 0=成功  0以外=メモリ不足
  283. {
  284.     int size;
  285.     if (EIMgetxsize() <= AREAXLEN)
  286.         areasizevar = NO, areaxlen = AREAXLEN;
  287.     else
  288.         areasizevar = YES, areaxlen=(EIMgetxsize()+7)&0xffff8;
  289.     areaylen = EIMgetysize();
  290.     size = (areaxlen / 8) * areaylen;
  291.     if (area_buf == NULL)
  292.     {
  293.         if ((area_buf = calloc(1,size)) == NULL)
  294.         {
  295.             DEBUG_MSG("領域指定バッファ用メモリ領域 確保失敗");
  296.             return -1;
  297.         }
  298.         else
  299.             DEBUG_MSG("領域指定バッファ用メモリ領域 確保成功");
  300.     }
  301.     if (xbuf == NULL)
  302.     {
  303.         if ((xbuf = (areapos**)malloc(sizeof(areapos*)*areaylen)) == NULL)
  304.             return -1;
  305.         memset(xbuf, 0, sizeof(areapos*) * areaylen);
  306.     }
  307.     if (xbuf[0] == NULL) {
  308.         bool error = NO;
  309.         int i;
  310.         for (i=0; i<areaylen; i++)
  311.         {
  312.             if ((xbuf[i] = (areapos*)malloc(sizeof(areapos)*XBUFMAX)) == NULL)
  313.                 { error = YES;  break; }
  314.         }
  315.         if (error)
  316.         {
  317.             DEBUG_MSG("area_polygon 領域指定ポリゴン描画用ワーク 確保失敗");
  318.             return -1;
  319.         }
  320.         DEBUG_MSG("area_polygon 領域指定ポリゴン描画用ワーク 確保成功");
  321.     }
  322.     if (px == NULL)
  323.     {
  324.         if ((px = (areapos*)malloc(sizeof(areapos)*MAXP*2)) == NULL)
  325.             return -1;
  326.         py = px + MAXP;
  327.         pnum = 0;
  328.     }
  329.     return 0;
  330. }
  331.  
  332.  
  333. static void area_clear()
  334. {
  335.     memset(area_buf, 0, (areaxlen >> 3)*areaylen);
  336. }
  337.  
  338.  
  339. static void area_hline(int x1,int x2,int y)
  340. {
  341.     char *p;  int x,leftx,rightx,xr1,xr2;
  342.     if (x1 > x2)
  343.         swap(x1,x2);
  344.     p = area_buf + (areaxlen >> 3) * y + (x1 >> 3);
  345.     leftx = x1 & 0xfff8;
  346.     xr1 = x1 & 7;
  347.     rightx = x2 & 0xfff8;
  348.     xr2 = x2 & 7;
  349.     if (leftx == rightx)
  350.     {
  351.         *p |= (0xff << xr1) & (0xff >> (7-xr2));
  352.     }
  353.     else
  354.     {
  355.         x = leftx;
  356.         *p++ |= (0xff << xr1) & 0xff,  x += 8;    // 左端
  357.         while (x < rightx)                        // 真ん中
  358.             *p++ = 0xff,  x += 8;
  359.         *p |= (0xff >> (7-xr2));                // 右端
  360.     }
  361. }
  362.  
  363.  
  364.  
  365. static void area_polygon(areapos *xlist,areapos *ylist)
  366. {
  367.     int i;
  368.     for (i=0; i<areaylen; i++)
  369.         *xbuf[i] = RIGHTMAX;
  370.     int getsign(int n)
  371.     {
  372.         return (n<0 ? -1 : n>0 ? 1 : 0);
  373.     }
  374.     int f1,f2,pnum;
  375.     for (pnum=0; xlist[pnum]>=0; pnum++)    // 頂点の数をかぞえる
  376.         ;
  377.     // 始点での頂点の例外処理のために、前の辺の符号をきめる
  378.     f1=0;
  379.     for (i=1; i<pnum; i++) {
  380.         f2=getsign(ylist[i]-ylist[i-1]);
  381.         if (f2!=0)
  382.             f1=f2;
  383.     }
  384.     f2=getsign(ylist[0]-ylist[pnum-1]);
  385.     if (f2!=0)
  386.         f1=f2;
  387.     // x 座標リストの作成
  388.     void makebuf(int x1,int y1,int x2,int y2)
  389.     {
  390.         int xmax,ymax;
  391.         xmax = EIMgetxsize()-1;
  392.         ymax = EIMgetysize()-1;
  393.         void sort_x()        // (x1,y1) をバッファに登録する
  394.         {
  395.             if (x1<0 || xmax<x1 || y1<0 || ymax<y1)
  396.                 return;
  397.             int i;
  398.             for (i=0; i<XBUFMAX; i++)
  399.             {
  400.                 if (xbuf[y1][i] > x1)
  401.                 {
  402.                     int j;
  403.                     if (i==XBUFMAX-1)
  404.                     {
  405.                         xbuf[y1][i] = x1;
  406.                         return;
  407.                     }
  408.                     for (j=XBUFMAX-1; j>i; j--)
  409.                         xbuf[y1][j] = xbuf[y1][j-1];
  410.                     xbuf[y1][i] = x1;
  411.                     break;
  412.                 }
  413.             }
  414.         }
  415.         int f2;
  416.         f2 = getsign(y2-y1);
  417.         if (f2==0)
  418.             return;
  419.         if (f1*f2==-1)
  420.             sort_x();
  421.         int dx,dy,ux,uy;
  422.         dx = abs(x2-x1);
  423.         dy = abs(y2-y1);
  424.         ux = getsign(x2-x1);
  425.         uy = getsign(y2-y1);
  426.         if (dx >= dy) {
  427.             int r = dx/2;
  428.             for (;;) {
  429.                 if (x1==x2) {
  430.                     f1=f2;
  431.                     break;
  432.                 }
  433.                 x1 += ux, r += dy;
  434.                 if (r >= dx) {
  435.                     r -= dx, y1 += uy;
  436.                     sort_x();
  437.                 }
  438.             }
  439.         } else {
  440.             int r = dy/2;
  441.             for (;;) {
  442.                 if (y1==y2) {
  443.                     f1=f2;
  444.                     break;
  445.                 }
  446.                 y1 += uy, r += dx;
  447.                 if (r >= dy)
  448.                     r -= dy, x1 += ux;
  449.                 sort_x();
  450.             }
  451.         }
  452.     }
  453.     for (i=0; i<pnum-1; i++)
  454.         makebuf(xlist[i],ylist[i],xlist[i+1],ylist[i+1]);
  455.     makebuf(xlist[pnum-1],ylist[pnum-1],xlist[0],ylist[0]);
  456.     // 領域バッファへの出力
  457.     for (i=0; i<areaylen; i++) {
  458.         int j;
  459.         for (j=0; j<XBUFMAX; j+=2) {
  460.             if (_max(xbuf[i][j],xbuf[i][j+1]) < areaxlen)
  461.                 area_hline(xbuf[i][j],xbuf[i][j+1],i);
  462.             else
  463.                 break;
  464.         }
  465.     }
  466. }
  467.  
  468.  
  469.  
  470.  
  471. int area_input(int type)
  472. // type  0=AREA_BOX  1=AREA_POLYGON
  473. // 返値: 0=承認  1=取消
  474. {
  475.     int lat2xlen, lat2ylen;
  476.     DMimage_getlatticesize(&lat2xlen,&lat2ylen);
  477.     area_clear();
  478.     if (type == AREA_BOX)
  479.     {
  480.         int step = 0;
  481.         int x1=0,y1=0,x2,y2;
  482.         void drawcsr(int msx,int msy)
  483.         {
  484.             if (step==1)
  485.             {
  486.                 int tx,ty;
  487.                 tx = DMimage_getx(msx),  ty = DMimage_gety(msy);
  488.                 int p1,p2,p3,p4;
  489.                 p1=x1,p2=y1,p3=tx,p4=ty;
  490.                 if (p1 > p3)
  491.                     swap(p1,p3);
  492.                 if (p2 > p4)
  493.                     swap(p2,p4);
  494.                 if (areaadj)
  495.                 {
  496.                     p1 = p1 - p1 % lat2xlen;
  497.                     p2 = p2 - p2 % lat2ylen;
  498.                     p3 = p3 - p3 % lat2xlen + lat2xlen - 1;
  499.                     p4 = p4 - p4 % lat2ylen + lat2ylen - 1;
  500.                     p3 = _min(p3,areaxlen-1);
  501.                     p4 = _min(p4,areaylen-1);
  502.                 }
  503.                 MOFF; EIMboxline(p1, p2, p3, p4, white, DrawXOR); MON;
  504.             }
  505.         }
  506.         pnum=-1;
  507.         for(;;)
  508.         {
  509.             int prex,prey;
  510.             if (step == 0 || areaadj)
  511.                 DMdispcsr(ms.x,ms.y);
  512.             drawcsr((prex=ms.x),(prey=ms.y));
  513.             do
  514.                 ms_get(&ms);
  515.             while (ms.dx==0 && ms.dy==0 && ms.btn1==OFF && ms.btn2==OFF &&
  516.                    key_chk()==0);
  517.             if (step == 0 || areaadj)
  518.                 DMerasecsr();
  519.             drawcsr(prex,prey);        // 消去
  520.             scrollForCsr(1,1);
  521.             if (ms.btn1==OFFON)
  522.             {
  523.                 if (step==0)             // 始点指定
  524.                     step=1, x1=DMimage_getx(ms.x), y1=DMimage_gety(ms.y);
  525.                 else if (step==1)         // 終点指定
  526.                 {
  527.                     x2=DMimage_getx(ms.x), y2=DMimage_gety(ms.y);
  528.                     if (x1 > x2)
  529.                         swap(x1,x2);
  530.                     if (y1 > y2)
  531.                         swap(y1,y2);
  532.                     if (areaadj)
  533.                     {
  534.                         x1 = x1 - x1 % lat2xlen;
  535.                         y1 = y1 - y1 % lat2ylen;
  536.                         x2 = x2 - x2 % lat2xlen + lat2xlen - 1;
  537.                         y2 = y2 - y2 % lat2ylen + lat2ylen - 1;
  538.                         x2 = _min(x2,areaxlen-1);
  539.                         y2 = _min(y2,areaylen-1);
  540.                     }
  541.                     int y;
  542.                     for (y=y1; y<=y2; y++)
  543.                         area_hline(x1,x2,y);
  544.                     ax1 = x1, ay1 = y1, ax2 = x2, ay2 = y2;
  545.                     return 0;
  546.                 }
  547.             }
  548.             if (ms.btn2==OFFON)
  549.             {
  550.                 if (step==0)
  551.                     return -1;
  552.                 else if (step==1)
  553.                     step=0;
  554.             }
  555.         }
  556.     }
  557.     else
  558.     {
  559.         bool first;
  560. POLY_RETRY:
  561.         pnum = 0;
  562.         px[0] = py[0] = -1;
  563.         ax1 = ay1 = 0xffff;
  564.         ax2 = ay2 = 0;
  565.         void drawcsr(int msx,int msy)
  566.         {
  567.             int tx,ty;
  568.             tx = DMimage_getx(msx),  ty = DMimage_gety(msy);
  569.             if (pnum > 0)
  570.             {
  571.                 int x1,y1;
  572.                 x1 = px[pnum-1], y1 = py[pnum-1];
  573.                 MOFF; EIMline(x1,y1,tx,ty,white,DrawXOR); MON;
  574.             }
  575.         }
  576.         first = YES;
  577.         for (;;)
  578.         {
  579.             int pre_x,pre_y;
  580.             DMdispcsr(ms.x, ms.y);
  581.             drawcsr(ms.x, ms.y);
  582.             pre_x = ms.x,  pre_y = ms.y;
  583.             do
  584.                 ms_get(&ms);
  585.             while (ms.dx == 0 && ms.dy == 0 &&
  586.                    ms.btn1 == OFF && ms.btn2 == OFF &&
  587.                    key_chk() == 0);
  588.             DMerasecsr();
  589.             drawcsr(pre_x, pre_y);    // 消去
  590.             scrollForCsr(1,1);
  591.             if ((ms.btn1 == OFFON || (ms.btn1 == ON && !first)) &&
  592.                 ms.btn2 == OFF)
  593.             {
  594.                 if (pnum < MAXP-1)
  595.                 {
  596.                     int tx,ty;
  597.  
  598.                     tx = DMimage_getx(ms.x),  ty = DMimage_gety(ms.y);
  599.                     if (pnum == 0 || tx!=px[pnum-1] || ty!=py[pnum-1])
  600.                     {
  601.                         if (tx < ax1)
  602.                             ax1 = tx;
  603.                         if (ax2 < tx)
  604.                             ax2 = tx;
  605.                         if (ty < ay1)
  606.                             ay1 = ty;
  607.                         if (ay2 < ty)
  608.                             ay2 = ty;
  609.                         px[pnum] = tx,  py[pnum] = ty;
  610.                         if (pnum >= 1)
  611.                         {
  612.                             int x1,y1,x2,y2;
  613.                             x1 = px[pnum-1], y1 = py[pnum-1];
  614.                             x2 = px[pnum  ], y2 = py[pnum  ];
  615.                             MOFF;
  616.                             EIMline(x1,y1,x2,y2,white,DrawXOR);
  617.                             EIMpset(x2,y2,white,DrawXOR);
  618.                             MON;
  619.                         }
  620.                         pnum++;
  621.                     }
  622.                 }
  623.             }
  624.             if (ms.btn1 == OFF || ms.btn1 == ONOFF)
  625.                 first = NO;
  626.             if (ms.btn2 == ONOFF)
  627.             {
  628.                 // ラバー表示を消す
  629.                 int i;
  630.                 for (i=1; i<pnum; i++)
  631.                 {
  632.                     int x1,y1,x2,y2;
  633.                     x1 = px[i-1], y1 = py[i-1];
  634.                     x2 = px[i  ], y2 = py[i  ];
  635.                     MOFF;
  636.                     EIMline(x1,y1,x2,y2,white,DrawXOR);
  637.                     EIMpset(x2,y2,white,DrawXOR);
  638.                     MON;
  639.                 }
  640.                 if (pnum == 0)
  641.                     goto POLY_CANCEL;
  642.                 else if (pnum >= 3 && (ms.btn1 == OFF || ms.btn1 == ONOFF))
  643.                     goto POLY_ACCEPTED;
  644.                 else
  645.                     goto POLY_RETRY;
  646.             }
  647.         }
  648. POLY_ACCEPTED:
  649.         px[pnum] = py[pnum] = -1;
  650.         if (pnum >= 3)
  651.             area_polygon(px,py);
  652.         return 0;
  653. POLY_CANCEL:
  654.         return -1;
  655.     }
  656. }
  657.  
  658.  
  659. void area_drawbound()
  660. {
  661.     if (pnum == -1)
  662.     {
  663.         MOFF; EIMboxline(ax1,ay1,ax2,ay2,white,DrawXOR); MON;
  664.     }
  665.     else if (pnum >= 3)
  666.     {
  667.         int i;
  668.         for (i=1; i<pnum; i++)
  669.         {
  670.             int x1,y1,x2,y2;
  671.             x1 = px[i-1], y1 = py[i-1];
  672.             x2 = px[i  ], y2 = py[i  ];
  673.             MOFF;
  674.             EIMline(x1,y1,x2,y2,white,DrawXOR);
  675.             EIMpset(x2,y2,white,DrawXOR);
  676.             MON;
  677.         }
  678.         MOFF;
  679.         EIMline(px[pnum-1],py[pnum-1],px[0],py[0],white,DrawXOR);
  680.         EIMpset(px[0],py[0],white,DrawXOR);
  681.         MON;
  682.     }
  683. }
  684.  
  685.  
  686. static char bit8[] = {1,2,4,8,16,32,64,128};
  687.  
  688.  
  689. bool area_chkxy(int x, int y)    // (x,y) が領域指定されているかを調べる
  690. {
  691.     if (x < 0 || y < 0 || areaxlen <= x || areaylen <= y)
  692.         return NO;
  693.     if (!areasizevar)
  694.     {
  695.         char r = (x & 7);
  696.         return (*(area_buf+y*(AREAXLEN/8)+(x>>3)) & bit8[r]) == 0 ? NO : YES;
  697.     }
  698.     else
  699.     {
  700.         char r = (x & 7);
  701.         return (*(area_buf+y*(areaxlen>>3)+(x>>3)) & bit8[r]) == 0 ? NO : YES;
  702.     }
  703. }
  704.  
  705.  
  706. bool area_chkxy2(int x,int y)    // (x,y)-(x+1,y+1)が領域指定されているか
  707. {
  708.     if (x+1 < 0 || y+1 < 0 || areaxlen <= x || areaylen <= y)
  709.         return NO;
  710.     char *p;
  711.     int xsize;
  712.     if (!areasizevar)
  713.         p = area_buf+y*(AREAXLEN/8)+(x>>3), xsize = AREAXLEN;
  714.     else
  715.         p = area_buf+y*(areaxlen>>3)+(x>>3), xsize = areaxlen;
  716.     int r = (x & 7);
  717.     if (0 <= y)
  718.     {
  719.         if (0 <= x)
  720.         {
  721.             if ((*p & bit8[r]) != 0)
  722.                 return YES;
  723.         }
  724.         if (x+1 < xsize)
  725.         {
  726.             if (r == 7)
  727.                 { if ((*(p+1) & bit8[0]) != 0)  return YES; }
  728.             else
  729.                 { if ((*p & bit8[r+1]) != 0)  return YES; }
  730.         }
  731.     }
  732.     if (y+1 < areaylen)
  733.     {
  734.         p += (xsize>>3);
  735.         if (0 <= x)
  736.         {
  737.             if ((*p & bit8[r]) != 0)
  738.                 return YES;
  739.         }
  740.         if (x+1 < xsize)
  741.         {
  742.             if (r == 7)
  743.                 { if ((*(p+1) & bit8[0]) != 0)  return YES; }
  744.             else
  745.                 { if ((*p & bit8[r+1]) != 0)  return YES; }
  746.         }
  747.     }
  748.     return NO;
  749. }
  750.  
  751.  
  752. int area_chkxylen(int x,int xmax,int y,bool nega)
  753. // (x,y) から右に何ドット連続して指定されているかを調べる(or 0)
  754. // nega: 働きを逆にする(領域指定されていない点の連続数を求める)
  755. {
  756.     int _maxx = _min(xmax,areaxlen-1);
  757.     if (x > _maxx)
  758.         return 0;
  759.     int xbytes = areaxlen >> 3;
  760.     char *p = area_buf + y*xbytes + (x>>3);
  761.     int i,r;
  762.     if (!nega)
  763.     {
  764.         for (i=x,r=x&7; i<=_maxx; )
  765.         {
  766.             if (r==0 && *p == 255)
  767.             {
  768.                 i+=8, p++;
  769.                 continue;
  770.             }
  771.             else if ((*p & bit8[r]) == 0)
  772.                 break;
  773.             i++;
  774.             if (++r == 8)
  775.                 r=0, p++;
  776.         }
  777.     }
  778.     else
  779.     {
  780.         for (i=x,r=x&7; i<=_maxx; )
  781.         {
  782.             if (r==0 && *p == 0)
  783.             {
  784.                 i+=8, p++;
  785.                 continue;
  786.             }
  787.             else if ((*p & bit8[r]) != 0)
  788.                 break;
  789.             i++;
  790.             if (++r == 8)
  791.                 r=0, p++;
  792.         }
  793.     }
  794.     i = _min(_maxx+1, i);
  795.     return i-x;
  796. }
  797.  
  798.  
  799. void area_getboundxy(int *x1, int *y1, int *x2, int *y2)
  800. // 領域指定された部分を囲む矩形を取得
  801. {
  802.     *x1 = ax1;
  803.     *y1 = ay1;
  804.     *x2 = ax2;
  805.     *y2 = ay2;
  806. }
  807.  
  808.  
  809. /*--------------------------------------------------------*/
  810. /*         INT 23h, 24h の割り込みハンドラの登録          */
  811. /*          High-C 割り込み処理のサンプルより             */
  812. /*--------------------------------------------------------*/
  813.  
  814. #if 0
  815.  
  816.     typedef struct {
  817.         int selecter ;    // native vector selecter
  818.         int offset ;    // native vector offset
  819.         int real_vect ;    // real vector
  820.     } vector_t ;
  821.  
  822.     static vector_t    int23, int24 ;  // 過去のベクタの退避用
  823.  
  824.     #pragma Calling_convention( C_interrupt ) ; /*  割り込みルーチン開始  */
  825.  
  826.     static void int23h( Machine_status Stat )
  827.     {
  828.         Stat.Flags = Stat.Flags ;   /*  dummy  */
  829.         return ;                    /*  iret  */
  830.     }
  831.  
  832.     static void int24h( Machine_status Stat )
  833.     {
  834.         Stat.AX = 3 ;               /*  system call fault  */
  835.         return ;                    /*  iret  */
  836.     }
  837.  
  838.     #pragma Calling_convention() ;              /*  割り込みルーチン終了  */
  839.  
  840.     static void dos_extender_call( int interrupt, int param )
  841.     {
  842.         Registers.DS.W = getds() ;
  843.         Registers.AX.W = interrupt ;
  844.         Registers.CX.W = param ;
  845.         calldos() ;
  846.     }
  847.  
  848.     void ARTsetintvector( void )
  849.     // int 23h/24h の割り込みベクタを int23h()/int24h() に変更
  850.     {
  851.         union {
  852.             _far void (*ptr)() ;
  853.             struct {  unsigned int off ;  unsigned short seg ;  }  reg ;
  854.         } farptr23h, farptr24h ;
  855.  
  856.         /*  int 23h の退避  */
  857.         dos_extender_call( 0x2502, 0x0023 ) ;
  858.         int23.selecter = Registers.ES.W;
  859.         int23.offset = Registers.BX.R ;
  860.  
  861.         dos_extender_call( 0x2503, 0x0023 ) ;
  862.         int23.real_vect = Registers.BX.R ;
  863.  
  864.         farptr23h.ptr = (_far void (*)())int23h ;
  865.         Registers.DS.W = farptr23h.reg.seg ;
  866.         Registers.AX.W = 0x2506 ;
  867.         Registers.CX.W = 0x0023 ;
  868.         Registers.DX.R = farptr23h.reg.off ;
  869.         calldos() ;
  870.  
  871.         /*  int 24h の退避  */
  872.         dos_extender_call( 0x2502, 0x0024 ) ;
  873.         int24.selecter = Registers.ES.W ;
  874.         int24.offset = Registers.BX.R ;
  875.  
  876.         dos_extender_call( 0x2503, 0x0024 ) ;
  877.         int24.real_vect = Registers.BX.R ;
  878.  
  879.         // 割り込みベクタの設定(AX=2506H)
  880.         farptr24h.ptr = (_far void (*)())int24h ;
  881.         Registers.DS.W = farptr24h.reg.seg ;
  882.         Registers.AX.W = 0x2506 ;
  883.         Registers.CX.W = 0x0024 ;
  884.         Registers.DX.R = farptr24h.reg.off ;
  885.         calldos() ;
  886.     }
  887.  
  888.     void ARTresetintvector( void )
  889.     // int 23h/24h の割り込みベクタを元に戻す
  890.     {
  891.         /*  int 23h の復帰  */
  892.         Registers.AX.W = 0x2507 ;
  893.         Registers.CX.W = 0x0023 ;
  894.         Registers.DS.W = int23.selecter ;
  895.         Registers.DX.R = int23.offset ;
  896.         Registers.BX.R = int23.real_vect ;
  897.         calldos() ;
  898.  
  899.         /*  int 24h の復帰  */
  900.         Registers.AX.W = 0x2507 ;
  901.         Registers.CX.W = 0x0024 ;
  902.         Registers.DS.W = int24.selecter ;
  903.         Registers.DX.R = int24.offset ;
  904.         Registers.BX.R = int24.real_vect ;
  905.         calldos() ;
  906.     }
  907. #endif
  908.  
  909.     void ARTsetintvector( void )
  910.     {
  911.         FM_SetVector();
  912.     }
  913.     
  914.     void ARTresetintvector( void )
  915.     {
  916.         FM_ResetVector();
  917.     }
  918.  
  919. /*--------------------------------------------------------*/
  920. /*                      三角関数処理                      */
  921. /*--------------------------------------------------------*/
  922.  
  923. #if 0
  924.     deci *atan512_tbl;
  925. #endif
  926.  
  927. int mathtbl_init(void)
  928. {
  929. #if 0
  930.     if ((atan512_tbl = (deci*)malloc(sizeof(deci)*(DUNIT+1))) == NULL)
  931.     {
  932.         return -1;
  933.     }
  934.     int i;
  935.     for (i=0; i<=DUNIT; i++)
  936.         atan512_tbl[i] = FD(atan((double)i / DUNIT) * 512.0 / (2*_PI));
  937. #endif
  938.     return 0;
  939. }
  940.  
  941. deci atan512(int theta)
  942. {
  943. #if 0
  944.     if (theta > DUNIT)
  945.         theta = DUNIT;
  946.     else if (theta < 0)
  947.         theta = 0;
  948.     return atan512_tbl[theta];
  949. #else
  950.     return 0;
  951. #endif
  952. }
  953.  
  954. #if 0
  955.  
  956. static    int        *__sin, *__cos;
  957.  
  958.  
  959. int math32_init(void)
  960. {
  961.     char *p;
  962.     if ((p = malloc(sizeof(int)*
  963.     
  964. }
  965.  
  966.  
  967. void math32_end(void)
  968. {
  969. }
  970.  
  971. #endif
  972.  
  973.  
  974. void hline_func(int x1, int x2, int y, void func(int x1, int x2, int y)!)
  975. {
  976.     int ix = x1;
  977.     while (ix <= x2)
  978.     {
  979.         int l1 = mask_chkxylen(ix,x2,y,NO);
  980.         ix += l1;
  981.         if (ix > x2)
  982.             break;
  983.         int l2 = mask_chkxylen(ix,x2,y,YES);
  984.         if (l2 > 0)
  985.             func(ix,ix+l2-1,y);
  986.         ix += l2;
  987.         if (l1 <= 0 && l2 <=0)
  988.             break;
  989.     }
  990. }
  991.  
  992. /* end of sub.c */
  993.